package com.plat.api.api.action;

import java.math.BigDecimal;
import java.util.Date;

import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.plat.api.common.OrderType;
import com.plat.api.common.RespCode;
import com.plat.api.dao.api.*;
import com.plat.api.entity.api.*;
import com.plat.api.exception.PlatException;
import com.plat.api.util.SnowflakeIdWorker;
import com.plat.api.util.YmalPropertiesUtil;
import com.plat.common.utils.StringUtils;
import com.plat.framework.redis.RedisCache;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * Created with IntelliJ IDEA.
 * User: shish
 * Date: 2020/6/14
 * Time: 0:32
 * Description: No Description
 */
@Service
public class PayAction implements OrderType {
    @Autowired
    private WxPayService wxService;
    @Autowired
    private UserDao userDao;
    @Autowired
    private TokenDao tokenDao;
    @Autowired
    private PlatVideoDao platVideoDao;
    @Autowired
    private PlatOrderDao platOrderDao;
    @Autowired
    private PlatOrderDetailDao platOrderDetailDao;
    @Autowired
    private PlatAuctionDao platAuctionDao;
    @Autowired
    private PlatAuctionOrderDao platAuctionOrderDao;
    @Autowired
    private PlatAuctionOrderRecordDao platAuctionOrderRecordDao;

    @Autowired
    private RedisCache redisCache;
    @Autowired
    private PlatAddressDao platAddressDao;

    /**
     * 直接支付时候创建订单
     * 订单开启事务支持
     */
    @Transactional
    public JSONObject CreatePayOrder(JSONObject paramJson) throws WxPayException {
        JSONObject body = paramJson.getJSONObject("body");
        Integer id = body.getInteger("id");
        UserEntity userEntity = getUserEntity(paramJson);
        PlatVideoEntity platVideoEntity = platVideoDao.getSQLManager().lambdaQuery(PlatVideoEntity.class).andEq("id", id).single();
        WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
        String outTradeNo = SnowflakeIdWorker.getId();
        request.setOpenid(userEntity.getOpenId());
        String payBody = StringUtils.substring(platVideoEntity.getDetail(), 0, 25) + "...";
        request.setBody(payBody);
        request.setOutTradeNo(outTradeNo);
        Double p = platVideoEntity.getPrice() * 100;
        request.setTotalFee(p.intValue());
        request.setSpbillCreateIp("0.0.0.0");
        request.setNotifyUrl(YmalPropertiesUtil.getValue("wxpay.notify-url").toString());
        request.setTradeType("JSAPI");
        WxPayMpOrderResult wxPayMpOrderResult = wxService.createOrder(request);
        if (wxPayMpOrderResult != null) {
            redisCache.setCacheObject(outTradeNo, outTradeNo);
            createOrder(platVideoEntity, userEntity, outTradeNo);
        } else {
            //String code, String msg, String desc,Object param
            throw new PlatException(RespCode.CREATE_ORDER_FAIL.getCode(), "微信支付创建订单失败", RespCode.CREATE_ORDER_FAIL.getError_msg(), RespCode.CREATE_ORDER_FAIL.getError_msg());
        }
        JSONObject json = new JSONObject();
        json.put("payInfo", wxPayMpOrderResult);
        return json;
    }

    private UserEntity getUserEntity(JSONObject paramJson) {
        String token = paramJson.getJSONObject("head").getString("token");
        TokenEntity tokenEntity = tokenDao.getSQLManager().lambdaQuery(TokenEntity.class).andEq("token", token).single();
        return userDao.getSQLManager().lambdaQuery(UserEntity.class).andEq("id", tokenEntity.getUserId()).single();
    }

    private void createOrder(PlatVideoEntity platVideoEntity, UserEntity userEntity, String outTradeNo) {
        PlatOrderEntity order = new PlatOrderEntity();
        order.setDeliveryId(0);
        //order.setOrderCouponId(0);
        order.setOrderStatus(OrderType.CREATE_ORDER);
        order.setPayStatus(OrderType.NO_PAY);
        //order.setPayType(0);
        order.setUserId(userEntity.getId());
        order.setOrderCouponPrice(new BigDecimal("0"));
        order.setOrderNo(outTradeNo);
        Double p = platVideoEntity.getPrice();
        order.setOrderPrice(new BigDecimal(p.doubleValue()));
        order.setOrderRealPrice(new BigDecimal(p.doubleValue()));
        //order.setOrderSn("");
        order.setOrderType(OrderType.VIDE0);
        order.setPhone(userEntity.getPhone());
        order.setCreateTime(new Date());
        order.setPayTime(null);
        order.setExpressStatus(OrderType.ORDER_EXPRESS_NO_DISTRIBUTE);
        order.setRefundStatus(OrderType.ORDER_NO_REFUND);
        order.setUserName(userEntity.getNickname());
        order.setPayType(WECHAT_PAY);
        platOrderDao.insert(order);
        //插入订单明细
        PlatOrderDetailEntity detail = new PlatOrderDetailEntity();
        detail.setOrderNo(order.getOrderNo());
        detail.setGoodsId(platVideoEntity.getId());
        detail.setCreateTime(new Date());
        detail.setPublisherId(userEntity.getId());
        detail.setCreateTime(new Date());
        detail.setUserId(userEntity.getId());
        detail.setOrderType(OrderType.AUCTION);
        detail.setGoodsType(platVideoEntity.getGoodsType());
        platOrderDetailDao.insert(detail);
    }


    /**
     * 创建实物订单
     */
    @Transactional
    public JSONObject createRealOrder(JSONObject paramJson) throws WxPayException {
        JSONObject body = paramJson.getJSONObject("body");
        Integer id = body.getInteger("id");
        Integer addressId = body.getInteger("addressId");
        Integer num = body.getInteger("num");//加价幅度*加价格次数 前端调整次数 最低一分钱
        UserEntity userEntity = getUserEntity(paramJson);
        PlatAuctionOrderEntity order = platAuctionOrderDao.getSQLManager().lambdaQuery(PlatAuctionOrderEntity.class).andEq("goods_id", id).andEq("user_id", userEntity.getId()).single();
        if (order == null) {
            if (addressId == null) {
                throw new PlatException(RespCode.CREATE_ORDER_ADDRESS_NULL.getCode(), RespCode.CREATE_ORDER_ADDRESS_NULL.getError_msg());
            }
        } else {
            if (addressId == null) {
                if (order.getAddressId() == null) {
                    throw new PlatException(RespCode.CREATE_ORDER_ADDRESS_NULL.getCode(), RespCode.CREATE_ORDER_ADDRESS_NULL.getError_msg());
                }
            }
        }
        AuctionEntity auctionEntity = platAuctionDao.unique(id);
        WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
        //计算最终需要支付的金额
        //TODO 计算金额
        Double amount =auctionEntity.getRangePrice()*num*100;
        String outTradeNo = SnowflakeIdWorker.getId();
        request.setOpenid(userEntity.getOpenId());
        String payBody = StringUtils.substring(auctionEntity.getDetail(), 0, 25) + "...";
        request.setBody(payBody);
        request.setOutTradeNo(outTradeNo);
        request.setTotalFee(amount.intValue());
        request.setSpbillCreateIp("0.0.0.0");
        request.setNotifyUrl(YmalPropertiesUtil.getValue("wxpay.notify-url").toString());
        request.setTradeType("JSAPI");
        WxPayMpOrderResult wxPayMpOrderResult = wxService.createOrder(request);
        if (wxPayMpOrderResult != null) {
            redisCache.setCacheObject(outTradeNo, outTradeNo);
            addressId = order == null ? addressId : order.getAddressId() == null ? addressId : order.getAddressId();
            create(auctionEntity, userEntity, outTradeNo, Double.valueOf(amount), addressId);
        } else {
            //String code, String msg, String desc,Object param
            throw new PlatException(RespCode.CREATE_ORDER_FAIL.getCode(), "微信支付创建订单失败", RespCode.CREATE_ORDER_FAIL.getError_msg(), RespCode.CREATE_ORDER_FAIL.getError_msg());
        }
        JSONObject json = new JSONObject();
        json.put("payInfo", wxPayMpOrderResult);
        return json;
    }

//    private Integer calculateMoney(UserEntity userEntity, AuctionEntity auctionEntity, Integer num) {
//        PlatOrderDetailEntity detailEntity = platOrderDetailDao.getSQLManager().lambdaQuery(PlatAuctionOrderEntity.class).andEq("goods_id", auctionEntity.getId()).andEq("user_id", userEntity.getId()).andEq("goods_type", OrderType.AUCTION).single();
//        Double amount = platAuctionOrderRecordDao.getMAXAmount(Integer.valueOf(auctionEntity.getId().toString()));
//        //PlatAuctionOrderRecordEntity
//        return amount.intValue();
//    }

    private void create(AuctionEntity auctionEntity, UserEntity userEntity, String outTradeNo, Double amount, Integer addressId) {
        PlatOrderDetailEntity detailEntity = platOrderDetailDao.getSQLManager().lambdaQuery(PlatOrderDetailEntity.class).andEq("goods_id", auctionEntity.getId()).andEq("user_id", userEntity.getId()).single();
        PlatAuctionOrderRecordEntity record = new PlatAuctionOrderRecordEntity();
        Double am = amount / 100;
        record.setPayMoney(am);
        record.setPayStatus(NO_PAY);
        record.setPayTime(new Date());
        record.setAuctionMainOrder(outTradeNo);
        record.setUserId(userEntity.getId());
        record.setCreateTime(new Date());
        record.setOutTradeNo(outTradeNo);
        record.setPaySn(null);
        record.setRefundStatus(ORDER_NO_REFUND);
        record.setRefundTime(new Date());
        record.setGoodsId(Integer.valueOf(auctionEntity.getId().toString()));
        platAuctionOrderRecordDao.insert(record);
        if (detailEntity == null) {
            PlatOrderEntity order = new PlatOrderEntity();
            order.setDeliveryId(addressId);
            order.setOrderCouponId(0);
            order.setOrderStatus(AUCTION_CREATE_ORDER);
            order.setPayStatus(NO_PAY);
            order.setUserId(userEntity.getId());
            order.setOrderCouponPrice(new BigDecimal("0"));
            order.setOrderNo(outTradeNo);
            order.setOrderPrice(new BigDecimal(auctionEntity.getBasePrice()));
            order.setOrderRealPrice(new BigDecimal(auctionEntity.getBasePrice()));
            order.setOrderType(OrderType.AUCTION);
            order.setPayType(WECHAT_PAY);
            order.setPhone(userEntity.getPhone());
            order.setCreateTime(new Date());
            order.setUserName(userEntity.getNickname());
            PlatOrderDetailEntity detail = new PlatOrderDetailEntity();
            detail.setOrderNo(order.getOrderNo());
            detail.setGoodsId(auctionEntity.getId());
            detail.setCreateTime(new Date());
            detail.setPublisherId(userEntity.getId());
            detail.setCreateTime(new Date());
            detail.setUserId(userEntity.getId());
            detail.setOrderType(OrderType.AUCTION);
            detail.setGoodsType(OrderType.AUCTION);
            detail.setOrderType(auctionEntity.getGoodsType());
            platOrderDetailDao.insert(detail);
            platOrderDao.insert(order);
            record.setAuctionMainOrder(outTradeNo);
            platAuctionOrderRecordDao.updateById(record);
        }
    }

}
